package 
{
	
	/**
	 * ...
	 * @author DarkGoodWIN
	 */
	
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.Loader;
	import flash.display.MovieClip;
	import flash.geom.ColorTransform;
	import flash.events.MouseEvent;
	import flash.net.URLRequest;
	import flash.system.System;

	public class TBaseContainer extends TControl 
	{
		public var fParent: TControl;
		public var Ctrls: Array; // <TControl>;
		public var Vert: Boolean = false;
		public var FirstItemIndex: int = -1;
		public var BorderWidth: Number = 5;
		private var fLinesCount: int = 1;
		public var MaxElementHeight: int = 0;
		private var fLockCount: int;
		public var Scrolling: BaseScrolling = null;
	    public var ScrollByOneItem: Boolean = true;
		
		private function InScrollRect(C: TControl): Boolean
		{
			return ((C.X + C.Width > Ctrl.scrollRect.x) && (C.Y + C.Height > Ctrl.scrollRect.y) &&
			        (C.X < Ctrl.x + Ctrl.width) && (C.Y < Ctrl.y + Ctrl.height));
		}
		
		public function LastItemIndex(): int
		{
			for (var i: int = Ctrls.length - 1; i > -1; --i)
			{
				var CC: TControl = Ctrls[i];
				if (InScrollRect(CC))
					return i;
			}
			return -1;
		}
		
		public function FindControlByObjectTarget(target: Object): TControl
		{
			var C: TControl = null;
			for (var I: int = 0; I < Ctrls.length; ++I)
			{
				var CC: TControl = Ctrls[I];
				if ((CC.Ctrl as DisplayObjectContainer).getChildAt(0) == target)
					return Ctrls[I];
			}
			return null;
		}
		
		public function UnLock(): void
		{
			--fLockCount;
		}
	
		public function Locked(): Boolean
		{
			return fLockCount > 0;
		}
		
		public function Lock(): void
		{
			++fLockCount;
		}
		
		protected function get ScrollWidth(): int
		{
			if (Scrolling != null)
				return Scrolling.ScrollWidth
			else
				return 0;
		}
		
		private var fVisible: Boolean = true;
	
		public override function get Visible(): Boolean
		{
			return fVisible;
		}
		
		public function ControlIndex(aCtrl: TControl): int
		{
			return Ctrls.indexOf(aCtrl);
		}

		public function PeekControl(aCtrl: TControl): int
		{
			var Res: int = ControlIndex(aCtrl);
			if (Res > -1)
			{
				Ctrls.splice(Res, 1);		
				RepaintChilds();
			}
			return Res;
		}
		
		public function DeleteControl(aCtrl: TControl): void
		{
			PeekControl(aCtrl);
			aCtrl.Ctrl.parent.removeChild(aCtrl.Ctrl);
			RepaintChilds();
		}
		
		public function Move2Left(): void
		{
			if (FirstItemIndex > 0)
			{
				--FirstItemIndex;
				RepaintChilds();
			}		
		}

		public function Move2Right(): void
		{
			if (FirstItemIndex < Ctrls.length)
			{
				++FirstItemIndex;
				RepaintChilds();
			}				
		}
		
		public function List2Right(): void
		{
			var N: int = LastItemIndex();
			if (N > -1)
			{
				FirstItemIndex = N;
				RepaintChilds();			
			}
		}
	
		public function List2Left(): void
		{
			var N: int = FirstItemIndex;
			while (LastItemIndex() > N)
			{
				Move2Left();
				if (FirstItemIndex == 0)
					return;
			}
		}
		
		protected function SetScrollVisible(v: Boolean): void
		{
			if (Scrolling != null)
				Scrolling.SetScrollVisible(v);
		}
	
		public override function set Visible( v : Boolean ):void
		{
			fVisible = v;
			SetScrollVisible(v);
			RepaintChilds();
		}
		
		public function AddControl(aCtrl: TControl): void
		{
			AddControlAt(Ctrls.length, aCtrl);
		}
		
		private function CorrectFirstItemIndX(): void
		{
			var CurPos: int = 2 * (ScrollWidth + BorderWidth);
			for (var i: int = Ctrls.length - 1; i >= 0; --i)
			{	
				var C: TControl = Ctrls[i];
				CurPos += C.Width + BorderWidth;
				if (CurPos > Width)
					return;
				if (i < FirstItemIndex)
					--FirstItemIndex;
			}
		}
	
		private function CorrectFirstItemIndY(): void
		{
			var CurPos: int = 2 * (ScrollWidth + BorderWidth);
			for (var i: int = Ctrls.length - 1; i >= 0; --i)
			{	
				var C: TControl = Ctrls[i];
				CurPos += C.Height + BorderWidth;
				if (CurPos > Height)
					return;
				if (i < FirstItemIndex)
					--FirstItemIndex;
			}
		}
		
		private function RepaintChildsX(): void
		{
			var CurLine: int = 1;
			var StartY: Number = Y + BorderWidth;
			var StartX: Number = X + BorderWidth + ScrollWidth;
		
			for ( var i: int = FirstItemIndex; i < Ctrls.length; ++i ) 
			{
				var C: TControl = Ctrls[i];
				C.X = StartX;
				C.Y = StartY;
				StartX += C.Width + BorderWidth;
				if (StartX + ScrollWidth + BorderWidth > X + Width + BorderWidth)
				{
					++CurLine;
					if (CurLine <= fLinesCount)
					{
						StartX = X + BorderWidth + ScrollWidth;
						StartY += C.Height + BorderWidth;
						C.X = StartX;
						C.Y = StartY;
						StartX += C.Width + BorderWidth;
					}
				}
			}
		}
	
		private function RepaintChildsY(): void
		{		
			var StartX: Number = X + BorderWidth;
			var StartY: Number = Y + BorderWidth + ScrollWidth;
						  		  
			for ( var i: int = FirstItemIndex; i < Ctrls.length; ++i ) 
			{
				var C: TControl = Ctrls[i];
				C.X = StartX;
				C.Y = StartY;
				StartY += C.Height + BorderWidth;
			}
		}
		
		private function CorrectFirstItemInd(): void
		{
			if (Vert)
				CorrectFirstItemIndY()
			else
				CorrectFirstItemIndX();
			
			if (FirstItemIndex < 0)
				FirstItemIndex = 0;
		}
		
		private function BeforeCtrlsHeigth(BeforeInd: int): Number
		{
			var Res: Number = 0;
			for ( var i: int = 0; i < BeforeInd; ++i ) 
			{
				var C: TControl = Ctrls[i];
				Res += C.Height + BorderWidth;
			}			
			return Res;			
		}
		
		public function AllCtrlsHeight(): Number
		{
			return BeforeCtrlsHeigth(Ctrls.length);
		}
		
		public function BeforeFirstItemHeight(): Number
		{
			return BeforeCtrlsHeigth(FirstItemIndex);
		}

		public function RepaintChilds(): void
		{
			for ( var I: int = 0; I < Ctrls.length; ++I )
				(Ctrls[I] as TControl).Visible = Visible;
			if (!(Visible))
				return;
			if (!(Locked))
				return;
			
			CorrectFirstItemInd();
		
			if (Vert)
				RepaintChildsY()
			else
				RepaintChildsX();
			
			UpdateScrollView();
		}
		
		protected function UpdateScrollView(): void
		{
			if (Scrolling != null)
				Scrolling.UpdateScrollView();			
		}

		protected function CalcAllBounds(): void
		{
			for ( var i: int = FirstItemIndex; i < Ctrls.length; ++i ) 
			{
				var C: TControl = Ctrls[i];
				CalcBonds(C);
			}
			RepaintChilds();
		}

		public function SetLinesCount(aCount: int): void
		{
			fLinesCount = aCount;
			CalcAllBounds();
		}
	
		public function CalcBonds(aCtrl: TControl): void
		{
			var Mul: Number = 1;
			if (Vert)
				Mul = (Width - 2 * BorderWidth) / aCtrl.Width
			else
				Mul = (Height - 2 * BorderWidth - (fLinesCount - 1) * BorderWidth) / aCtrl.Height;
			
			if ((MaxElementHeight > 0) && Vert)
				Mul = Math.min(Mul, MaxElementHeight / aCtrl.Height);
			
			if ((fLinesCount > 1) && (!(Vert)))
				Mul = Mul / fLinesCount;
			
			if ((Mul <= 0.0001) || (Mul > 10000))
				return;
			aCtrl.Ctrl.scaleX = aCtrl.Ctrl.scaleX * Mul;
			aCtrl.Ctrl.scaleY = aCtrl.Ctrl.scaleY * Mul;
		}
		
		public function AddControlAt(Index: int, aCtrl: TControl): void
		{
			if (Ctrls.indexOf(aCtrl) >= 0)
				return;
			try
			{
				if (FirstItemIndex < 0)
					FirstItemIndex = 0;
				for (var i: int = Ctrls.length; i > Index; --i)
					Ctrls[i] = Ctrls[i - 1];
				Ctrls[Index] = aCtrl;				
				DebugParent.AddChild(aCtrl);
				CalcBonds(aCtrl);
				RepaintChilds();			
			}
			catch (e: Error)
			{
				new Ttext(e.toString(), DebugParent);	
			}		
		}
		
		public function sortOn (names:*, options:* = 0, ...rest) : Array
		{
			var aCtrls: Array = Ctrls.sortOn(names, options);
			for (var I: int = 0; I < Ctrls.length; ++I)
				Ctrls[I] = aCtrls[I];
			RepaintChilds();
			return aCtrls;
		}
		
		public function Init(): void
		{
			if (Scrolling != null)
				Scrolling.Init();			
		}

		public function TBaseContainer(Parent: TControl, aX: Number, anY: Number, aWidth: Number, aHeight: Number)
		{
			var Pic: MovieClip = new MovieClip;
			super(Pic, Parent, aX, anY);
			Pic.graphics.drawRect(aX, anY, aWidth, aHeight);
			Width = aWidth;
			Height = aHeight;	
			fParent = Parent;
			
			Ctrls = new Array();
		}
	}
}